package cn.dugcrs.basic.service.impl;

import cn.dugcrs.basic.constant.BaseConstants;
import cn.dugcrs.basic.dto.RegisterDto;
import cn.dugcrs.basic.exception.BusinessException;
import cn.dugcrs.basic.service.IVerifyCodeService;
import cn.dugcrs.basic.utils.EmailUtil;
import cn.dugcrs.basic.utils.SmsSendUtils;
import cn.dugcrs.basic.utils.StrUtils;
import cn.dugcrs.basic.utils.VerifyCodeUtils;
import cn.dugcrs.user.domain.User;
import cn.dugcrs.user.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IUserService userService;

    @Autowired
    private JavaMailSender javaMailSender;


    /**
     * 图片验证码生成
     * @param key
     * @return
     */
    @Override
    public String getImgCode(String key) {
        String code = VerifyCodeUtils.generateVerifyCode(4);
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        // System.out.println("图片验证");
        return VerifyCodeUtils.VerifyCode(98, 34, code);
    }


    /**
     * 发送短信验证码
     * @param dto
     * @return
     */
    @Override
    public void smsCode(RegisterDto dto) {
        String phone = dto.getPhone();
        String type = dto.getType();
        // 空校验
        if (phone == null
                || type == null) {
            throw new BusinessException("参数不能为空！！！");
        }
        if (dto.getType().equals("register")) {
            registerCode(dto);
        } else if (dto.getType().equals("binder")) {
            binderCode(dto);
        }

    }

    /**
     * 发送短信验证码
     */
    public void sendSmsCode(String key) {
        // 产生新的验证码
        String code = StrUtils.getComplexRandomString(4);
        // 通过key获取code+时间戳，如果存在则不是第一发短信，如果是第一次进入则直接跳过下面的if判断
        String codeStr = (String)redisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(codeStr)){
            // 如果有效，并且已经过重发时间，替换验证码
            String timeStr = codeStr.split(":")[1];
            if (System.currentTimeMillis()-Long.valueOf(timeStr)<1000*60*1) {
                throw new BusinessException("非法操作！");
            }
            code = codeStr.split(":")[0];
        }
        // 4 存到redis
        redisTemplate.opsForValue().set(key,code+":"+System.currentTimeMillis(),3, TimeUnit.MINUTES);
        //5 发送短信验证码给用户
        // SmsSendUtils.sendSms(phone,"你的验证码为："+code+",请在3分钟内使用！");
        System.out.println("你的验证码为：" + code + ",请在3分钟内使用！");

    }



    /**
     * 账号绑定短信业务
     * @param dto
     */
    public void binderCode(RegisterDto dto) {
        String key = BaseConstants.SmsCodeConstants.BUSINESS_BINDER_PREFIX + dto.getPhone();
        sendSmsCode(key);
    }


    /**
     * 手机号注册短信业务
     * @param dto
     */
    public void registerCode(RegisterDto dto) {
        String phone = dto.getPhone();
        String imageCodeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
        // 空校验
        if (phone == null
                || imageCodeKey == null
                || imageCodeValue == null) {
            throw new BusinessException("参数不能为空！！！");
        }
        // 比较图形验证码
        Object ImageCodevalue = redisTemplate.opsForValue().get(imageCodeKey);
        if(ImageCodevalue == null ){
            throw new BusinessException("无效的图片验证码或过期，请重新输入");
        }
        if(!dto.getImageCodeValue().equalsIgnoreCase(ImageCodevalue.toString())){
            throw new BusinessException("错误的图片验证码，请重新输入");
        }

        // 校验手机号是否被注册
        User user = userService.loadByPhone(dto.getPhone());
        if (user != null) {
            throw new BusinessException("该手机号已经注册。请直接登录！");
        }

        // 判断原来的验证码是否有效
        String key = BaseConstants.SmsCodeConstants.BUSINESS_REGISTER_PREFIX + phone;
        sendSmsCode(key);
    }










    /**
     * 发送邮箱验证码
     * @param dto
     */
    @Override
    public void emailSmsCode(RegisterDto dto) {
        String email = dto.getEmail();
        String imageCodeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
        // 空校验
        if (email == null
                || imageCodeKey == null
                || imageCodeValue == null) {
            throw new BusinessException("参数不能为空！！！");
        }
        // 比较图形验证码
        Object ImageCodevalue = redisTemplate.opsForValue().get(imageCodeKey);
        if(ImageCodevalue == null ){
            throw new BusinessException("无效的图片验证码或过期，请重新输入");
        }
        if(!dto.getImageCodeValue().equalsIgnoreCase(ImageCodevalue.toString())){
            throw new BusinessException("错误的图片验证码，请重新输入");
        }

        // 校验邮箱是否被注册
        User user = userService.loadByEmail(email);
        if (user != null) {
            throw new BusinessException("该邮箱已经注册。请直接登录！");
        }

        // 判断原来的验证码是否有效
        String key = BaseConstants.SmsCodeConstants.BUSINESS_REGISTER_PREFIX + email;
        // 产生新的验证码
        String code = StrUtils.getComplexRandomString(4);
        // 通过key获取code+时间戳，如果存在则不是第一发短信，如果是第一次进入则直接跳过下面的if判断
        String codeStr = (String)redisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(codeStr)){
            // 如果有效，并且已经过重发时间，替换验证码
            String timeStr = codeStr.split(":")[1];
            if (System.currentTimeMillis()-Long.valueOf(timeStr)<1000*60*1) {
                throw new BusinessException("非法操作！");
            }
            code = codeStr.split(":")[0];
        }
        // 4 存到redis
        redisTemplate.opsForValue().set(key,code+":"+System.currentTimeMillis(),3, TimeUnit.MINUTES);
        //5发送短信验证码给用户
        // SmsSendUtils.sendSms(phone,"你的验证码为："+code+",请在3分钟内使用！");
        EmailUtil.sendMail("3133046533@qq.com","宠物乐园邮箱注册","亲，您的验证码为：" + code + ",请在3分钟内使用！",email);

        System.out.println("你的验证码为：" + code + ",请在3分钟内使用！");
    }
}
